module MapEditor
  class TilePanel < Gtk::VBox
    attr_reader :frame
    attr_accessor :sx, :sy, :ex, :ey
    attr_accessor :active, :controler
    attr_reader :zoom
    attr_accessor :left_pressed, :right_pressed
    
    def initialize(zoom)
      super
      @sx = 0
      @sy = 0
      @ex = 0
      @ey = 0
      @zoom = zoom
      @frame = Frame.new
      @left_pressed = false
      @right_pressed = false
      @controler = nil
    end
    
    def zoom=(value)
      return if @zoom == value
      @zoom = value
      @scroll_box.set_client_size(self.max_x_count * self.zoomed_grid_width, self.max_y_count * self.zoomed_grid_height)
      @scroll_box.grid_width = self.zoomed_grid_width
      @scroll_box.grid_height = self.zoomed_grid_height
      @scroll_box.refresh_scrollbars
      @scroll_box.on_resize
    end
    
    def x_count
      return @scroll_box.x_count
    end
    
    def y_count
      return @scroll_box.y_count
    end

    def max_x_count
      return @scroll_box.max_x_count
    end
    
    def max_y_count
      return @scroll_box.max_y_count
    end
    
    def zoomed_grid_width
      return self.grid_width * @zoom
    end
    
    def zoomed_grid_height
      return self.grid_height * @zoom
    end
    
    def get_abs_location(x, y , b = true)
      sx = (([x, 0].max + self.scroll_x) / self.zoomed_grid_width.to_f).floor
      sy = (([y, 0].max + self.scroll_y) / self.zoomed_grid_height.to_f).floor

      if(b)
        sx = [sx, self.right_count - @frame.width].min
        sy = [sy, self.bottom_count - @frame.height].min
      end
      return sx, sy
    end
    
    def set_panel
      self.add(@scroll_box)
    end
    
    def set_signals
      @scroll_box.signal_connect("motion-notify-event") do |item, event|
        self.on_motion(event)
      end
      
      @scroll_box.signal_connect("button-press-event") do |item, event|
        case(event.button)
          when 1
            self.on_left_down(event)
          when 3
            self.on_right_down(event)
        end
      end
      
      @scroll_box.signal_connect("button-press-event", Gdk::Event::BUTTON2_PRESS) do |item, event|
        self.on_double_clicked(event) 
      end

      @scroll_box.signal_connect("button-release-event") do |item, event|
        case(event.button)
          when 1
            self.on_left_up(event)
          when 3
            self.on_right_up(event)
        end
      end       
    end
    
    ###############
    # these methods are not recommended
    def scroll_x_count
      return @scroll_box.left_count
    end
    
    def scroll_y_count
      return @scroll_box.top_count
    end
    ###############
    
    def left_count
      return @scroll_box.left_count
    end
    
    def top_count
      return @scroll_box.top_count
    end
    
    def right_count
      return @scroll_box.right_count
    end
    
    def bottom_count
      return @scroll_box.bottom_count
    end
    
    def scroll_x
      return self.scroll_x_count * self.zoomed_grid_width
    end
    
    def scroll_y
      return self.scroll_y_count * self.zoomed_grid_height  
    end
    
    def render_grid(texture, grid_width, grid_height)
      (0..self.x_count - 1).each do |i|
        texture.render_line(i * grid_width, 0, i * grid_width, texture.height, Color.new(255, 255, 255, 60))
      end
      (0..self.y_count - 1).each do |i|
        texture.render_line(0, i * grid_height, texture.width, i * grid_height, Color.new(255, 255, 255, 60))
      end
    end
    
    # Events
    def on_left_down(e)
      return if @left_pressed || @controler.nil?
      @left_pressed = true
      @controler.on_left_down(e)
    end
    
    def on_left_up(e)
      return if !@left_pressed || @controler.nil?
      @left_pressed = false
      @controler.on_left_up(e)
    end

    def on_right_down(e)
      return if @right_pressed || @controler.nil?
      @right_pressed = true
      @controler.on_right_down(e)
    end

    def on_right_up(e)
      return if !@right_pressed || @controler.nil?
      @right_pressed = false
      @controler.on_right_up(e)
    end

    def on_motion(e)
      return if @controler.nil?
      @controler.on_motion(e)
    end
    
    def on_double_clicked(e)
      return if @controler.nil?
      @controler.on_double_clicked(e)
    end
  end
end